// Copyright 2017-2018 Intel Corporation.

#include <string>

#include "tile/hal/cm/err.h"

namespace vertexai {
namespace tile {
namespace hal {
namespace cm {

const char* getErrorString(int Code) {
  if (Code == CM_SUCCESS) return nullptr;

  static const char* ErrorStrings[] = {
#define ENUM_STRING(e) #e
      ENUM_STRING(CM_SUCCESS),
      ENUM_STRING(CM_FAILURE),
      ENUM_STRING(CM_NOT_IMPLEMENTED),
      ENUM_STRING(CM_SURFACE_ALLOCATION_FAILURE),
      ENUM_STRING(CM_OUT_OF_HOST_MEMORY),
      ENUM_STRING(CM_SURFACE_FORMAT_NOT_SUPPORTED),
      ENUM_STRING(CM_EXCEED_SURFACE_AMOUNT),
      ENUM_STRING(CM_EXCEED_KERNEL_ARG_AMOUNT),
      ENUM_STRING(CM_EXCEED_KERNEL_ARG_SIZE_IN_BYTE),
      ENUM_STRING(CM_INVALID_ARG_INDEX),
      ENUM_STRING(CM_INVALID_ARG_VALUE),
      ENUM_STRING(CM_INVALID_ARG_SIZE),
      ENUM_STRING(CM_INVALID_THREAD_INDEX),
      ENUM_STRING(CM_INVALID_WIDTH),
      ENUM_STRING(CM_INVALID_HEIGHT),
      ENUM_STRING(CM_INVALID_DEPTH),
      ENUM_STRING(CM_INVALID_COMMON_ISA),
      ENUM_STRING(CM_D3DDEVICEMGR_OPEN_HANDLE_FAIL),
      ENUM_STRING(CM_D3DDEVICEMGR_DXVA2_E_NEW_VIDEO_DEVICE),
      ENUM_STRING(CM_D3DDEVICEMGR_LOCK_DEVICE_FAIL),
      ENUM_STRING(CM_EXCEED_SAMPLER_AMOUNT),
      ENUM_STRING(CM_EXCEED_MAX_KERNEL_PER_ENQUEUE),
      ENUM_STRING(CM_EXCEED_MAX_KERNEL_SIZE_IN_BYTE),
      ENUM_STRING(CM_EXCEED_MAX_THREAD_AMOUNT_PER_ENQUEUE),
      ENUM_STRING(CM_EXCEED_VME_STATE_G6_AMOUNT),
      ENUM_STRING(CM_INVALID_THREAD_SPACE),
      ENUM_STRING(CM_EXCEED_MAX_TIMEOUT),
      ENUM_STRING(CM_JITDLL_LOAD_FAILURE),
      ENUM_STRING(CM_JIT_COMPILE_FAILURE),
      ENUM_STRING(CM_JIT_COMPILESIM_FAILURE),
      ENUM_STRING(CM_INVALID_THREAD_GROUP_SPACE),
      ENUM_STRING(CM_THREAD_ARG_NOT_ALLOWED),
      ENUM_STRING(CM_INVALID_GLOBAL_BUFFER_INDEX),
      ENUM_STRING(CM_INVALID_BUFFER_HANDLER),
      ENUM_STRING(CM_EXCEED_MAX_SLM_SIZE),
      ENUM_STRING(CM_JITDLL_OLDER_THAN_ISA),
      ENUM_STRING(CM_INVALID_HARDWARE_THREAD_NUMBER),
      ENUM_STRING(CM_GTPIN_INVOKE_FAILURE),
      ENUM_STRING(CM_INVALIDE_L3_CONFIGURATION),
      ENUM_STRING(CM_INVALID_D3D11_TEXTURE2D_USAGE),
      ENUM_STRING(CM_INTEL_GFX_NOTFOUND),
      ENUM_STRING(CM_GPUCOPY_INVALID_SYSMEM),
      ENUM_STRING(CM_GPUCOPY_INVALID_WIDTH),
      ENUM_STRING(CM_GPUCOPY_INVALID_STRIDE),
      ENUM_STRING(CM_EVENT_DRIVEN_FAILURE),
      ENUM_STRING(CM_LOCK_SURFACE_FAIL),
      ENUM_STRING(CM_INVALID_GENX_BINARY),
      ENUM_STRING(CM_FEATURE_NOT_SUPPORTED_IN_DRIVER),
      ENUM_STRING(CM_QUERY_DLL_VERSION_FAILURE),
      ENUM_STRING(CM_KERNELPAYLOAD_PERTHREADARG_MUTEX_FAIL),
      ENUM_STRING(CM_KERNELPAYLOAD_PERKERNELARG_MUTEX_FAIL),
      ENUM_STRING(CM_KERNELPAYLOAD_SETTING_FAILURE),
      ENUM_STRING(CM_KERNELPAYLOAD_SURFACE_INVALID_BTINDEX),
      ENUM_STRING(CM_NOT_SET_KERNEL_ARGUMENT),
      ENUM_STRING(CM_GPUCOPY_INVALID_SURFACES),
      ENUM_STRING(CM_GPUCOPY_INVALID_SIZE),
      ENUM_STRING(CM_GPUCOPY_OUT_OF_RESOURCE),
      ENUM_STRING(CM_DEVICE_INVALID_D3DDEVICE),
      ENUM_STRING(CM_SURFACE_DELAY_DESTROY),
      ENUM_STRING(CM_INVALID_VEBOX_STATE),
      ENUM_STRING(CM_INVALID_VEBOX_SURFACE),
      ENUM_STRING(CM_FEATURE_NOT_SUPPORTED_BY_HARDWARE),
      ENUM_STRING(CM_RESOURCE_USAGE_NOT_SUPPORT_READWRITE),
      ENUM_STRING(CM_MULTIPLE_MIPLEVELS_NOT_SUPPORTED),
      ENUM_STRING(CM_INVALID_UMD_CONTEXT),
      ENUM_STRING(CM_INVALID_LIBVA_SURFACE),
      ENUM_STRING(CM_INVALID_LIBVA_INITIALIZE),
      ENUM_STRING(CM_KERNEL_THREADSPACE_NOT_SET),
      ENUM_STRING(CM_INVALID_KERNEL_THREADSPACE),
      ENUM_STRING(CM_KERNEL_THREADSPACE_THREADS_NOT_ASSOCIATED),
      ENUM_STRING(CM_KERNEL_THREADSPACE_INTEGRITY_FAILED),
      ENUM_STRING(CM_INVALID_USERPROVIDED_GENBINARY),
      ENUM_STRING(CM_INVALID_PRIVATE_DATA),
      ENUM_STRING(CM_INVALID_MOS_RESOURCE_HANDLE),
      ENUM_STRING(CM_SURFACE_CACHED),
      ENUM_STRING(CM_SURFACE_IN_USE),
      ENUM_STRING(CM_INVALID_GPUCOPY_KERNEL),
      ENUM_STRING(CM_INVALID_DEPENDENCY_WITH_WALKING_PATTERN),
      ENUM_STRING(CM_INVALID_MEDIA_WALKING_PATTERN),
      ENUM_STRING(CM_FAILED_TO_ALLOCATE_SVM_BUFFER),
      ENUM_STRING(CM_EXCEED_MAX_POWER_OPTION_FOR_PLATFORM),
      ENUM_STRING(CM_INVALID_KERNEL_THREADGROUPSPACE),
      ENUM_STRING(CM_INVALID_KERNEL_SPILL_CODE),
      ENUM_STRING(CM_UMD_DRIVER_NOT_SUPPORTED),
      ENUM_STRING(CM_INVALID_GPU_FREQUENCY_VALUE),
      ENUM_STRING(CM_SYSTEM_MEMORY_NOT_4KPAGE_ALIGNED),
      ENUM_STRING(CM_KERNEL_ARG_SETTING_FAILED),
      ENUM_STRING(CM_NO_AVAILABLE_SURFACE),
      ENUM_STRING(CM_VA_SURFACE_NOT_SUPPORTED),
      ENUM_STRING(CM_TOO_MUCH_THREADS),
      ENUM_STRING(CM_NULL_POINTER),
      ENUM_STRING(CM_EXCEED_MAX_NUM_2D_ALIASES),
      ENUM_STRING(CM_INVALID_PARAM_SIZE),
      ENUM_STRING(CM_GT_UNSUPPORTED),
      ENUM_STRING(CM_GTPIN_FLAG_NO_LONGER_SUPPORTED),
      ENUM_STRING(CM_TASK_MEDIA_RESET),
#undef ENUM_STRING
  };

  const char* ErrorString = "Internal Error";
  if (Code > CM_INTERNAL_ERROR_CODE_OFFSET) ErrorString = ErrorStrings[-Code];

  return ErrorString;
}

int checkError(int Code, const char* Path, const int Line, bool Abort) {
  if (Code != CM_SUCCESS) {
    std::fprintf(stderr, "CM-ERROR: %s %s %d\n", getErrorString(Code), Path, Line);
    if (Abort) std::exit(Code);
  }
  return Code;
}

}  // namespace cm
}  // namespace hal
}  // namespace tile
}  // namespace vertexai
